package handler

import (
	"fmt"
	"gitee.com/lanshiren/miniprogram/app/log"
	"gitee.com/lanshiren/miniprogram/app/model"
	"gitee.com/lanshiren/miniprogram/app/service"
	"github.com/gin-gonic/gin"
	"strings"
)

// HandleCreateActivity ...
func HandleCreateActivity(c *gin.Context) {
	token := c.Request.Header.Get("token")
	userData, err := service.TryGetUserSession("session-" + token)
	if err != nil {
		return
	}
	openId := strings.Split(userData, "$")[0]
	user, err := service.GetUserByOpenID(openId)
	if err != nil {
		return
	}
	var activity model.ActivityVO
	if err := c.BindJSON(&activity); err != nil {
		log.MainLogger.Error(fmt.Sprintf("bind client json to activity err: %v", err))
	}
	// 创建活动的人就是领队
	activity.LeaderID = user.ID
	activity.Status = model.UnderReview
	if err := service.SaveActivity(&activity); err != nil {
		log.MainLogger.Error(fmt.Sprintf("save activity err: %v", err))
		c.JSON(500, gin.H{
			"result": NewResultRet(err.Error(), 500, nil),
		})
		return
	}
	c.JSON(200, gin.H{
		"result": NewResultRet("ok", 200, map[string]interface{}{
			"activity_id": activity.ID,
		}),
	})
}

// HandleGetActivityUsers ...
func HandleGetActivityUsers(c *gin.Context) {
	var param model.FetchActivityParam
	if err := c.BindQuery(&param); err != nil {
		log.MainLogger.Error(fmt.Sprintf("bind client json to SearchActivitiesParam err: %v", err))
	}
	acUserList, err := service.GetRegistrationUsers(uint(param.ID))
	if err != nil {
		c.JSON(500, gin.H{
			"result": NewResultRet(err.Error(), 500, nil),
		})
		return
	}
	c.JSON(200, gin.H{
		"result": NewResultRet("ok", 200, acUserList),
	})
}

// HandleGetActivity ...
func HandleGetActivity(c *gin.Context) {
	var param model.FetchActivityParam
	if err := c.BindQuery(&param); err != nil {
		log.MainLogger.Error(fmt.Sprintf("bind client json to SearchActivitiesParam err: %v", err))
	}
	// update cur count
	if err := service.UpdateRegisterUserCount(uint(param.ID)); err != nil {
		log.MainLogger.Error(fmt.Sprintf("GetActivity err: %v", err))
		c.JSON(500, gin.H{
			"result": NewResultRet(err.Error(), 500, nil),
		})
		return
	}
	ac, err := service.GetActivity(uint(param.ID))
	if err != nil {
		log.MainLogger.Error(fmt.Sprintf("GetActivity err: %v", err))
		c.JSON(500, gin.H{
			"result": NewResultRet(err.Error(), 500, nil),
		})
		return
	}
	useDo, err := service.QueryUserByID(ac.LeaderID)
	if err != nil {
		log.MainLogger.Error(fmt.Sprintf("QueryUserByID err: %v", err))
	}
	ac.LeaderName = useDo.Nickname
	ac.Phone = useDo.Phone
	token := c.Request.Header.Get("token")
	userData, err := service.TryGetUserSession("session-" + token)
	if err != nil {
		return
	}
	openId := strings.Split(userData, "$")[0]
	user, err := service.GetUserByOpenID(openId)
	if err != nil {
		c.JSON(500, gin.H{
			"result": NewResultRet(err.Error(), 500, nil),
		})
		return
	}
	// check user is already register
	isUserReAc, isRegisDone, err := service.HasUserRegisterActivity(user.ID, ac.ID)
	if err != nil {
		c.JSON(500, gin.H{
			"result": NewResultRet(err.Error(), 500, nil),
		})
		return
	}
	acUsersDo, err := service.GetRegistrationUsers(ac.ID)
	if err != nil {
		c.JSON(500, gin.H{
			"result": NewResultRet(err.Error(), 500, nil),
		})
		return
	}
	for _, acUser := range acUsersDo {
		ac.AvatarUrls = append(ac.AvatarUrls, acUser.AvatarUrl)
	}
	switch user.RoleId {
	case model.BlackUser:
		break
	case model.Admin:
		if ac.Status == model.Approved {
			if isUserReAc && isRegisDone {
				ac.ActionList = append(ac.ActionList, &model.ActionRes{"2", "取消报名"})
			} else {
				ac.ActionList = append(ac.ActionList, &model.ActionRes{"1", "报名"})
			}
		}
		if ac.Status != model.UnderReview && ac.Status != model.FailToPassReview {
			ac.ActionList = append(ac.ActionList, &model.ActionRes{"3", "编辑"})
		}
		if ac.Status == model.UnderReview {
			ac.ActionList = append(ac.ActionList, &model.ActionRes{"4", "审核通过"})
			ac.ActionList = append(ac.ActionList, &model.ActionRes{"5", "审核不通过"})
		}
		break
	case model.Editor:
		if ac.Status == model.Approved {
			if isUserReAc && isRegisDone {
				ac.ActionList = append(ac.ActionList, &model.ActionRes{"2", "取消报名"})
			} else {
				ac.ActionList = append(ac.ActionList, &model.ActionRes{"1", "报名"})
			}
		}
		if ac.Status != model.UnderReview && ac.Status != model.FailToPassReview {
			ac.ActionList = append(ac.ActionList, &model.ActionRes{"3", "编辑"})
		}
		if ac.Status == model.UnderReview {
			ac.ActionList = append(ac.ActionList, &model.ActionRes{"4", "审核通过"})
			ac.ActionList = append(ac.ActionList, &model.ActionRes{"5", "审核不通过"})
		}
		break
	case model.Leader:
		if ac.Status == model.Approved {
			if isUserReAc && isRegisDone {
				ac.ActionList = append(ac.ActionList, &model.ActionRes{"2", "取消报名"})
			} else {
				ac.ActionList = append(ac.ActionList, &model.ActionRes{"1", "报名"})
			}
		}
		if ac.Status != model.UnderReview && ac.Status != model.FailToPassReview {
			ac.ActionList = append(ac.ActionList, &model.ActionRes{"3", "编辑"})
		}
		break
	case model.SimpleUser:
		if ac.Status == model.Approved {
			if isUserReAc && isRegisDone {
				ac.ActionList = append(ac.ActionList, &model.ActionRes{"2", "取消报名"})
			} else {
				ac.ActionList = append(ac.ActionList, &model.ActionRes{"1", "报名"})
			}
		}
		break
	}
	c.JSON(200, gin.H{
		"result": NewResultRet("ok", 200, ac),
	})
}

// HandleSearchActivities ...
func HandleSearchActivities(c *gin.Context) {
	var param model.SearchActivitiesParam
	if err := c.BindQuery(&param); err != nil {
		log.MainLogger.Error(fmt.Sprintf("bind client json to SearchActivitiesParam err: %v", err))
	}
	total, acs, err := service.SearchActivities(param)
	if err != nil {
		log.MainLogger.Error(fmt.Sprintf("SearchActivities err: %v", err))
		c.JSON(500, gin.H{
			"result": NewResultRet(err.Error(), 500, nil),
		})
		return
	}
	c.JSON(200, gin.H{
		"result": NewResultRet("", 200, map[string]interface{}{
			"total":   total,
			"results": acs,
		}),
	})
}

// HandleUpdateActivity ...
func HandleUpdateActivity(c *gin.Context) {
	var param model.UpdateActivityParam
	if err := c.BindJSON(&param); err != nil {
		log.MainLogger.Error(fmt.Sprintf("bind client json to UpdateActivityParam err: %v", err))
	}
	if err := service.UpdateActivity(param); err != nil {
		log.MainLogger.Error(fmt.Sprintf("UpdateActivityParam err: %v", err))
		c.JSON(500, gin.H{
			"result": NewResultRet("", 500, nil),
		})
		return
	}
	c.JSON(200, gin.H{
		"result": NewResultRet("ok", 200, nil),
	})
}

// HandleVerifyActivity ...
func HandleVerifyActivity(c *gin.Context) {
	var param model.VerifyActivityParam
	if err := c.BindJSON(&param); err != nil {
		log.MainLogger.Error(fmt.Sprintf("bind client json to VerifyActivityParam err: %v", err))
	}
	// TODO: check request token has the permission to verify
	if param.IsApprove {
		if err := service.VerifyActivity(param.ID, model.Approved); err != nil {
			log.MainLogger.Error(fmt.Sprintf("VerifyActivity err: %v", err))
			c.JSON(500, gin.H{
				"result": NewResultRet(err.Error(), 500, nil),
			})
			return
		}
	} else {
		if err := service.VerifyActivity(param.ID, model.FailToPassReview); err != nil {
			log.MainLogger.Error(fmt.Sprintf("VerifyActivity err: %v", err))
			c.JSON(500, gin.H{
				"result": NewResultRet(err.Error(), 500, nil),
			})
			return
		}
	}
	c.JSON(200, gin.H{
		"result": NewResultRet("ok", 200, nil),
	})
}

// HandleRegistrationActivity ...
func HandleRegistrationActivity(c *gin.Context) {
	token := c.Request.Header.Get("token")
	userData, err := service.TryGetUserSession("session-" + token)
	if err != nil {
		return
	}
	openId := strings.Split(userData, "$")[0]
	user, err := service.GetUserByOpenID(openId)
	if err != nil {
		return
	}
	// TODO: check user has permission
	var param model.RegistrationActivityParam
	if err := c.BindJSON(&param); err != nil {
		log.MainLogger.Error(fmt.Sprintf("bind client json to RegistrationActivityParam err: %v", err))
	}
	if err := service.RegistrationActivity(user.ID, param.ActivityID); err != nil {
		log.MainLogger.Error(fmt.Sprintf("RegistrationActivity err: %v", err))
		c.JSON(500, gin.H{
			"result": NewResultRet(err.Error(), 500, nil),
		})
		return
	}
	c.JSON(200, gin.H{
		"result": NewResultRet("ok", 200, nil),
	})
}

// HandleCancelRegistrationActivity ...
func HandleCancelRegistrationActivity(c *gin.Context) {
	token := c.Request.Header.Get("token")
	userData, err := service.TryGetUserSession("session-" + token)
	if err != nil {
		return
	}
	openId := strings.Split(userData, "$")[0]
	user, err := service.GetUserByOpenID(openId)
	if err != nil {
		return
	}
	// TODO: check user has permission
	var param model.RegistrationActivityParam
	if err := c.BindJSON(&param); err != nil {
		log.MainLogger.Error(fmt.Sprintf("bind client json to RegistrationActivityParam err: %v", err))
	}
	if err := service.CancelRegistrationActivity(user.ID, param.ActivityID); err != nil {
		log.MainLogger.Error(fmt.Sprintf("CancelRegistrationActivity err: %v", err))
		c.JSON(500, gin.H{
			"result": NewResultRet(err.Error(), 500, nil),
		})
		return
	}
	c.JSON(200, gin.H{
		"result": NewResultRet("ok", 200, nil),
	})
}
